package com.gzcstec.ftp;

import org.apache.commons.net.ftp.FTPClient;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

public class FTPService {

    private FTPClientPool ftpClientPool;

    public FTPService(FTPClientPoolProperties ftpClientPoolProperties){
        ftpClientPool = new FTPClientPool(ftpClientPoolProperties);
    }

    public String uploadFromLocalSystemFile(String originFileName) {
        InputStream inputStream;
        try {
            inputStream = new FileInputStream(new File(originFileName));
            return upload(inputStream, getDotExt(originFileName));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public String getDotExt(String fileName){
        if(fileName==null) return "";
        int dotIndex = fileName.indexOf(".");
        if(dotIndex!=-1){
            return fileName.substring(dotIndex);
        }
        return "";
    }

    private String[] split2PathAndShortName(String fileName){
        String fileSeparator = ftpClientPool.getFtpClientPoolProperties().getFileSeparator();
        String resolveFileName = getResolveFileName(fileName);

        int index = resolveFileName.lastIndexOf(fileSeparator);
        String path=fileSeparator;
        String name=fileName;
        if(index>0){
            path = resolveFileName.substring(0,index);
        }
        if(index+1<resolveFileName.length()){
            name = resolveFileName.substring(index+1);
        }
        return new String[]{path,name};
    }

    public String upload(InputStream inputStream, String dotExtName, String ... args ) {
        if (inputStream==null) {
            return null;
        }
        String filePath=null;
        String fileName=null;
        if(args != null){
            if(args.length == 2){
                if(args[0] != null){
                    filePath = args[0].replace(File.separator,ftpClientPool.getFtpClientPoolProperties().getFileSeparator());
                }
                if(args[1] != null){
                    fileName = args[1];
                }
            }
        }
        //TODO 保存路径和文件名可以自定义生成
        String fileSeparator = ftpClientPool.getFtpClientPoolProperties().getFileSeparator();
        if(filePath==null){
            LocalDateTime now = LocalDateTime.now();
            filePath = fileSeparator + now.getYear() + fileSeparator + +now.getMonthValue() + fileSeparator +now.getDayOfMonth() + fileSeparator;
        }
        if(fileName==null){
            LocalDateTime now = LocalDateTime.now();
            Random random = new Random();
            fileName = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + random.nextInt(10000) + dotExtName;
        }
        FTPClient ftpClient = null;
        boolean result;
        try {
            ftpClient = ftpClientPool.borrowObject();
            makeAndChangeWorkDirectories(ftpClient,filePath);
            result = ftpClient.storeFile(fileName, inputStream);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (ftpClient != null) {
                ftpClientPool.returnObject(ftpClient);
            }
            try {
                inputStream.close();
            } catch (IOException e) {

            }
        }
        return result ? filePath + fileName : null;
    }

    public InputStream downloadAsStream(String remoteFullFileName){
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            String[] split = split2PathAndShortName(remoteFullFileName);
            makeAndChangeWorkDirectories(ftpClient,split[0]);
            InputStream inputStream = ftpClient.retrieveFileStream(split[1]);
            return inputStream;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (ftpClient != null) {
                ftpClientPool.returnObject(ftpClient);
            }
        }
    }

    public byte[] downloadAsByte(String remoteFullFileName){
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            String[] split = split2PathAndShortName(remoteFullFileName);
            makeAndChangeWorkDirectories(ftpClient,split[0]);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ftpClient.retrieveFile(split[1], out);
            return out.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (ftpClient != null) {
                ftpClientPool.returnObject(ftpClient);
            }
        }
    }

    private String getResolveFileName(String fileName){
        String fileSeparator = ftpClientPool.getFtpClientPoolProperties().getFileSeparator();
        String resolveFileName = fileName.replace("\\",fileSeparator).replace("/",fileSeparator);
        return resolveFileName;
    }

//    public String downloadAsBase64Str(String remoteFullFileName){
//        byte[] bytes = downloadAsByte(remoteFullFileName);
//        return Base64Util.bytesToBase64(bytes);
//    }

    /**
     * 切换FTP工作目录
     *
     * @param ftp
     * @param remoteFoldPath
     * @throws IOException
     */
    private static void makeAndChangeWorkDirectories(FTPClient ftp, String remoteFoldPath) throws IOException {
        String[] dirs = remoteFoldPath.split("\\\\|/");
        for (int i = 0; i < dirs.length; i++) {
            if(dirs[i].length()==0) continue;
            if (!ftp.changeWorkingDirectory(dirs[i])) {
                ftp.makeDirectory(dirs[i]);
                ftp.changeWorkingDirectory(dirs[i]);
            }
        }
    }
}
